---------------------------------
Part one: Introduction to Quake C
---------------------------------

 A) ACKNOWLEDGMENTS:

The Quake-C Consortium would like to thank the following
else this manual would not have come into existance:

ID Software (for actually having the temerity to design
	     and build the game Quake.)

Members of the Quake-C mailing list. Who Decided that this
was a NEEDED thing!!!

Members of the Quake-C consortium. (the guys with the blurry 
eyes and calloused fingertips for actually writing this
thing.

 B) COPYRIGHT:




		Copyright 1996 by the Quake-C Consortium. 

		Reproduction or publication of this Manual
		in any manner electronic or otherwise without
		the express written and signed permission of
		the Quake-C Consortium or it's desginate is 
		strictly prohibited. 

		Posting of this manual on the Internet by the
		Quake-C Consortium does not in anyway waive
		these rights. No liability is assumed with 
		respect to the use of the information herein.

		See Appendix for list of contributing Authors


Chapter 1: STARTING WITH QUAKE-C

 A) WHAT IS QUAKE-C:

Quake-C is the primary programming language of the Game Quake by 
ID Software.  Quake-C is the language which defines the behavior of 
the game. For example, it defines what happens when you fire a 
weapon, open a door, cross a certain area in a level, how the monsters
move, how you can attack a monster etc. This is not the source for the 
Quake Engine, rather, it is like a kind of enhanced scripting language 
that can be used to control the game and it's functions.  It is a bit 
like DeHackEd for Doom, except that it is 100 times more powerful and 
user-friendly (actually, I should say programmer-friendly).  Quake-C 
uses close to the same functions as the C Programming language, but 
it is highly modified and in it's current form, very hacked. 
John Carmack of ID software hopes to have a more streamlined 
version out at some later date. (two weeks???).

 B) WHO DESIGNED QUAKE-C AND WHY:

 John Carmack of ID software designed Quake-C as a way to customize 
the game Quake.  With the success of the games  Wolfenstein 3-D and 
Doom, players found ways to "Hack" these games and basically re-engineer 
the basic game levels with their own designs. As a result, the games 
became "engines" that allowed for a freedom that game players found 
enticing.  This caused both Wolf-3d and Doom to become great successes 
in their genre.  With the success of these games, ID decided from the 
start that they would design a game "Engine" that allowed for FULL 
customization of the "World".  Thus was born QUAKE and Quake-C. 

 Quake-C is a major component released by ID software as part of 
the quake utilities. (components or modules that allow for design 
and compilation of the separate parts of the game.) Here is what 
John Carmack of ID software has to say about the Quake-C compiler 
from the Readme.txt file that comes with the Quake-C source code.

 This is the last major component of the quake utilities to be 
released. To be honest, I have been a little  reticent to release 
this because most of the actual qc code is rather embarrassing crap. 
The time never became available to even give it a good top to bottom 
going over. I never spent any quality engineering  time on my parts, 
American wrote a lot of qc code, and even Romero has a bit of work in 
there. It is a mess.

If you look through the code and occasionally think "This is stupid!", 
you are probably right...
 
 The compiler itself can be drastically sped up by just replacing the 
symbol searches with binary trees or  hashing. We remotely compile 
on our alpha, so it hasn't  been a big enough issue for me to do it, 
but as the code  size grows and grows it will be done sooner or later.
The resulting code is horribly nieve and space  inefficient (twelve 
bytes / instruction). If common subexpression removal was added, 
the instruction count   could probably be cut nearly in half. I would 
have liked  to have done a better job at this, but this was my first  
compiler front end, and I had a ton of other things  fighting for my 
time. The next one will turn out better.  (wow, I'm making a lot of 
excuses here, aren't I?)

 Qcc also performs some other maintenance functions for us, like 
rebuilding all the brush models and making pak files, but those 
functions are only useful if you have created all new data for 
everything. models.qc and  sprites.qc don't actually generate any 
code, they are  just parsed by modelgen and spritegen and included 
for completeness.

 To modify the quake program code, set up a new game  directory 
parallel with id1, and containing a "progs"  subdirectory. Copy all 
the .qc files and progs.src into  that, and just run qcc from that 
directory. That will  compile all of the files listed in progs.src 
and (if  there aren't any errors) generate a new progs.dat file  
in the parent directory.

 As a simple test, open the client.qc file, go to the ClientObituary 
function at the end, and change some of the messages.

The directory structure will look something like: 
/quake/quake.exe /quake/id1/ 
/quake/mygame/progs.dat 
/quake/mygame/progs/progs.src 
/quake/mygame/progs/world.qc 
/quake/mygame/progs/client.qc 
/quake/mygame/progs/... etc. ... 

 Run quake with "-game mygame", which will cause quake to  
look for data in the mygame directory before falling  back to 
id1. In this example, it will find the new progs.dat from 
mygame, and take everything else from  id1. You can type 
"path" at the quake console to verify  the current search order 
of directories and pak files.
 
 THIS WILL ONLY WORK WITH A REGISTERED VERSION OF QUAKE.

 The header qcc.h has the language spec and some documentation, but 
I'm not positive if it is all current.

 The only documentation for the various built in functions I can 
offer is the source code used by quake. See builtin.c. Some of them 
are required to do things outside the scope of the qc world, and 
some are just there for speed reasons. PLEASE don't ask me 
questions about all this!

 John Carmack


 C) WHO SHOULD READ THIS MANUAL:

 Anyone who desires to customize or design a new game using the 
Quake Engine. If you are a Gamer, use a personal computer and are 
interested in designing or customizing Quake, then you will want 
to read this manual. If you are a novice, then the exciting field 
of 3-D computer animation and simulation is waiting for you to 
discover. If you are an experienced programmer in C, this manual 
will treat you to some unique programming techniques that you may 
have thought possible only through established game companies 
and elaborate software. The Manual is constructed in this way:

Part 1: Brief Introduction on the constructs of the Quake-C
	Language. This is to iniate the new person to the
	language. It goes from basic constructs to detailed
	explainations of the structure of the Quake-C language.

Part 2: This is where we go into detailed explainations of the
	Quake-C files, Quake-C Specifications, and Summeries of the
	files released with QCC (Quake C Compiler) including use 
	of the compiler and how to modify and re-compile the assembler.

Part 3: In this part, we have tutorials and examples of the Quake-C
	code and how it is used to design and build a completely NEW game
	using the Quake engine. We will actually perform walk-thru's of 
	building a completely playable and UNIQUE Quake level that includes
	a new model from scratch. From .MDL to the final .PAK file. 

Part 4: This part includes samples from the BEST of the BEST Quake-C Mods.

Part 5: Appendices, Glossery, Summery of Quake-C Language, Index.
 

 D) BASIC CONSTRUCTS OF THE QUAKE-C LANGUAGE

COMMENTS
---------
// comments discard text until the end of the line.

/*  */  comments discard all enclosed text. 
          Example:

          /*
          here is where info or notes you type
          will go, nothing here will be seen
          by the compiler. Handy for letting people
          know what your code means!!!
          */

CODE STRUCTURE
-------------
A definition is:
<type> <name> [ = <immediate>] {, <name> [ = <immediate>] };

TYPES
-----
simple types:  void, float, vector, string, or entity

float width,  height;
string  name;
entity  self,     other;

vector types:
vector org;  //   also creates org_x,  org_y,  org_z  float defs

A function type is specified as:  simpletype ( type name {,type name} )
The names are ignored except when the function is initialized.

void() think;
entity() FindTarget;
void(vector destination, float speed, void()  callback) SUB_CalcMove;
void(...) dprint; //   variable argument builtin

NAMES
------
Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, 
and can continue with those characters or 0-9.

There are two levels of scoping:  global, and function.  The parameter 
list of a function and any vars declared inside a function with the 
"local" statement are only visible within that function.

IMMEDIATES
----------
Float immediates must begin with 0-9 or minus sign.  .5 is illegal.

A parsing ambiguity is present with negative constants. "a-5" will be
parsed
as "a", then "-5", causing an error.  Separate the - from the digits with 
a space

"a - 5" 

to get the proper behavior.

1 2
1 . 6
0 . 5
- 1 0 0

Vector immediates are three float immediates enclosed in single quotes.
'0 0 0'
'20.5    -10   0.00001'

String immediates are characters enclosed in double quotes.  The string
cannot
contain explicit new lines, but the escape character \n can embed one.  the
\"
escape can be used to include a quote in the string.
"maps/jrwiz1.bsp"
"sound/nin/pain.wav"
"ouch!\n"

Code immediates are statements enclosed in {} braces.
statement:
{  <multiple statements>  }
<expression>;
local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
return <expression>;
if ( <expression> ) <statement>;
do <statement> while ( <expression> );
<function name> ( <function params> );

EXPRESSION
----------
Combinations of names and these operators with standard C precedence:
(See Chapter 2 for Detailed Explaination)

Arithmetic Operators:

	Multiplicative Operators:

		"*"	Multiplication
		"/"	Division
	
	Additive Operators:

		"-"	Subtraction
		"+"	Addition

Relational Operators:
		
		"<"	Less-than
		">"	Greater-than
		"<="	Less-than-or-equal to
		">="	Greater-than-or-equal to
		"!="	not-equal-to
		"=="	Equal-to

Assignment Operators

		"=" 	Assign new value to variable (see CH 2. for 
			detailed explaination) DO NOT Confuse with
			the Equal-to Operator above!!!

	Bitwise Operators: (The & and | operations perform integral bit ops on floats)
			   (See Chapter 2 for Detailed Explaination of these operators)

		"&"	Bitwise And
		"|"	Bitwise Or
		
	Logical Operators:

		"&&"	And
		"||"	Or
		"!"	Not (unary negation operator)
 
 
Parenthesis () can be used to alter order of operation.

 
A built in function immediate is a number sign followed by an integer.
 #1
 #12


COMPILATION
-----------
Source files are processed sequentially without dumping any state, so if a 
defs file is the first one processed, the definitions will be available to 
all other files.

The language is strongly typed and there are no casts.

Anything that is initialized is assumed to be constant, and will have 
immediates folded into it.  If you change the value, your program will 
malfunction.  All uninitialized globals will be saved to savegame files.

Functions cannot have more than eight parameters.

Error recovery during compilation is minimal.  It will skip to the next 
global definition, so you will never see more than one error at a time in a

given function.  All compilation aborts after ten error messages.

Names can be defined multiple times until they are defined with an 
initialization, allowing functions to be prototyped before their
definition.

void() MyFunction;   // the prototype

void() MyFunction =  // the initialization
{
 dprint ("we're here\n");
};


ENTITIES AND FIELDS
-------------------


execution
---------
Code execution is initiated by C code in quake from two main places:  the 
timed think routines for periodic control, and the touch function when two 
objects impact each other.

There are three global variables that are set before beginning code
execution:

 entity world;  // the server's world object, which holds all global
      		// state for the server, like the deathmatch flags
      		// and the body ques.

 entity self;   // the entity the function is executing for

 entity other;  // the other object in an impact, not used for thinks

 float time;    // the current game time.  Note that because the
      		// entities in the world are simulated sequentially,
      		// time is NOT strictly increasing.  An impact late
      		// in one entity's time slice may set time higher
      		// than the think function of the next entity. 
      		// The difference is limited to 0.1 seconds.

Execution is also caused by a few uncommon events, like the addition of a
new client to an existing server.
 
There is a runaway counter that stops a program if 100000 statements are 
executed, assuming it is in an infinite loop.

It is acceptable to change the system set global variables.  This is
usually done to pose as another entity by changing self and calling a 
function.

The interpretation is fairly efficient, but it is still over an order of 
magnitude slower than compiled C code.  All time consuming operations
should be made into built in functions.

A profile counter is kept for each function, and incremented for each 
interpreted instruction inside that function.  The "profile" console
command in Quake will dump out the top 10 functions, then clear all 
the counters.  The "profile all" command will dump sorted stats for 
every function thathas been executed.

afunc ( 4, bfunc(1,2,3));
will fail because there is a shared parameter marshaling area, which will 
cause the 1 from bfunc to overwrite the 4 already placed in parm0.  When a 
function is called, it copies the parms from the globals into it's
privately scoped variables, so there is no collision when calling another 
function.

total = factorial(3) + factorial(4);
Will fail because the return value from functions is held in a single
global area.  If this really gets on your nerves, tell me and I can 
work around it at a slight performance and space penalty by allocating 
a new register for the function call and copying it out.


built in functions
------------------
void(string text) dprint;
Prints the string to the server console.

void(entity client, string text) cprint;
Prints a message to a specific client.

void(string text) bprint;
Broadcast prints a message to all clients on the current server.

entity() spawn;
Returns a totally empty entity.  You can manually set everything up, or
just set the origin and call one of the existing entity setup functions.

entity(entity start, .string field, string match) find;
Searches the server entity list beginning at start, looking for an entity 
that has entity.field = match.  
To start at the beginning of the list, pass world.  
World is returned when the end of the list is reached.

<FIXME: define all the other functions...>


gotchas
-------

The && and || operators DO NOT EARLY OUT like C!

Don't confuse single quoted vectors with double quoted strings

The function declaration syntax takes a little getting used to.

Don't forget the ; after the trailing brace of a function initialization.

Don't forget the "local" before defining local variables.

There are no ++ / -- operators, or operate/assign operators.